import axios from 'axios';
import { Toast } from 'vant';
import GlobalParameters from './config';

axios.defaults.withCredentials = true; // 需要跨域携带认证
axios.defaults.headers.common['Content-Type'] = 'application/json;charset=UTF-8';
class Httprequest {
	private timeout: number;
	private queue: object;
	private loadingCount: number;
	constructor() {
		this.timeout = 50000; // 请求的超时时间50秒
		this.queue = {}; // 请求队列,防止重复点击
		this.loadingCount = 0;
	}

	_closeLoading(isLoading: boolean) {
		if (isLoading) {
			this.loadingCount--;
			if (this.loadingCount <= 0) {
				Toast.clear();
				this.loadingCount = 0;
			}
		}
	}

	setinterceptors(instance: any, isLoading: boolean, isCancel: boolean, unique: string) {
		instance.interceptors.request.use((config: any) => {
			if (config.method.toUpperCase() === 'GET') {
				config.params = { ...GlobalParameters, ...config.params };
			} else {
				// 文件流全局参数处理
				if (config.headers['Content-Type'] === 'multipart/form-data') {
					Object.keys(GlobalParameters).forEach(key => {
						config.data.append(key, GlobalParameters[key]);
					});
				} else {
					config.data = { ...GlobalParameters, ...config.data };
				}
			}
			if (this.queue[unique]) {
				throw 'EXCEPTION:REPEATCLICK';
			} else {
				this.queue[unique] = unique;
			}

			if (isLoading) {
				this.loadingCount++;
				Toast.loading({
					duration: 0,
					message: '加载中...',
					forbidClick: true,
				});
			}
			return config;
		});

		instance.interceptors.response.use(
			(res: any) => {
				delete this.queue[unique];
				this._closeLoading(isLoading);
				if (!res.data.success) {
					Toast(res.data.errorMessage);
					return Promise.reject(res.data);
				}
				return Promise.resolve(res.data.data);
			},
			(error: any) => {
				this._closeLoading(isLoading);
				if (error === 'EXCEPTION:REPEATCLICK') {
					Toast('请不要重复点击!!!');
				} else if (error.__proto__.constructor.name === 'Cancel') {
					delete this.queue[unique];
					console.log('请求取消');
				} else {
					delete this.queue[unique];
					Toast.fail('服务器异常');
				}

				return Promise.reject(error.message);
			}
		);
	}

	request(options: any, { isLoading = true, isCancel = true } = {}) {
		let instance = axios.create();
		options.method || (options.method = 'post');
		let config = {
			baseURL: '/api',
			timeout: this.timeout,
			...options,
		};
		// 确定唯一性(路由+接口地址+请求方式)
		const unique = `${location.href}${config.method}${config.url}`.toLocaleUpperCase();
		this.setinterceptors(instance, isLoading, isCancel, unique);
		return instance(config);
	}
}

const http = new Httprequest();

export default http.request.bind(http);
